package top.wshape1.shiziapi.uaa.controller;

import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.util.Base64Utils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.wshape1.shiziapi.common.constant.AuthConstant;
import top.wshape1.shiziapi.common.constant.BizCodeEnum;
import top.wshape1.shiziapi.uaa.domain.vo.UserLoginVo;
import top.wshape1.shiziapi.common.group.uaa.LoginGroup;
import top.wshape1.shiziapi.common.group.uaa.RegGroup;
import top.wshape1.shiziapi.common.group.uaa.ResetGroup;
import top.wshape1.shiziapi.common.utils.R;
import top.wshape1.shiziapi.uaa.domain.User;
import top.wshape1.shiziapi.uaa.service.UserService;

/**
 * @author Wshape1
 * @version 1.0
 * @description
 * @since 2023-08-22
 */

@RestController
public class LoginController {

    @Resource
    public UserService userService;

    /**
     * 登录并将token放置请求头
     *
     * @param userLoginVo email and password
     * @return
     */
    @PostMapping("/login")
    public R<Void> login(@Validated(LoginGroup.class)
                         @RequestBody UserLoginVo userLoginVo,
                         HttpServletResponse response) {

        String token = userService.login(userLoginVo);
        response.setHeader(AuthConstant.HEADER_NEW_TOKEN_NAME, token);

        return R.ok();
    }

    /**
     * 注册
     *
     * @param userLoginVo email, password and code
     * @return
     */
    @PostMapping("/reg")
    public R<String> reg(@Validated(RegGroup.class) @RequestBody UserLoginVo userLoginVo) {
        //  注册
        userService.reg(userLoginVo);

        return R.ok();
    }

    /**
     * 发送重置密码邮件
     *
     * @param emailEncoded 邮箱Base64加密
     * @return
     */
    @PostMapping("/forget/code")
    public R<String> forgetSend(@RequestParam("email") String emailEncoded) {

        String email = new String(Base64Utils.decodeFromString(emailEncoded));

        if (!email.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$")) {
            return R.instance(BizCodeEnum.INVALID_DATA_ERROR.code(), BizCodeEnum.INVALID_DATA_ERROR.msg());
        }
        // 发送重置密码邮件
        userService.sendForgetUrl(email);

        return R.ok();
    }

    /**
     * @param userLoginVo email, password, and code
     * @return
     */
    @PostMapping("/forget")
    public R<?> resetPassword(@Validated(ResetGroup.class) @RequestBody UserLoginVo userLoginVo) {

        userService.resetPassword(userLoginVo);

        return R.ok();
    }

    /**
     * 注销登录
     *
     * @param userEncoded 通过Base64加密的user信息串
     * @return
     */
    @PostMapping("/logout")
    public R<String> logout(@RequestHeader(AuthConstant.HEADER_PAYLOAD_NAME)
                            String userEncoded) {

        // 获取user json
        String userStr = new String(Base64Utils.decodeFromString(userEncoded));
        User user = JSON.parseObject(userStr, User.class);
        userService.logout(user);

        return R.ok();
    }

    /**
     * 发送验证码
     *
     * @param emailEncoded email Base64 加密
     * @return
     */
    @PostMapping("/reg/code")
    public R<?> verifyCode(@RequestParam("email") String emailEncoded) {

        String email = new String(Base64Utils.decodeFromString(emailEncoded));

        if (!email.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$")) {
            return R.instance(BizCodeEnum.INVALID_DATA_ERROR.code(), BizCodeEnum.INVALID_DATA_ERROR.msg());
        }

        userService.sendRegCode(email);

        return R.ok();
    }

}
